<?php

namespace App\Http\Controllers\Home;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Home\HomeCartNumber;
use App\Http\Controllers\Home\ShowLinksController;
use App\Http\Controllers\Api\IndexApi;
use DB;
use App\Model\Goods;
use App\Model\Goodsattr;
use App\Model\Goodsbrand;
use App\Model\Goodspic;
use App\Model\Goodssale;
use App\Model\Goodsspecs;
use App\Model\Goodstype;
use Illuminate\Support\Facades\Redis;

class ShopCartController extends Controller
{
    /**
     * Display a listing of the resource.
     * 展示购物车页面，拿到redis中用户购物车的数据然后显示在前台
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $session_id = session()->getId();
        $cartGoods = 'user_cart_attrid_set_'.$session_id;//redis中储存的是用户的购物车商品属性id信息
        $cartKey = 'user_cart_attrid_num_hash_'.$session_id;//redis中储存的是用户的商品属性id和对应的数量
        $cartGoodsInfoKey = 'user_cart_attrid_detail_hash_';//redis中跟sessionid和attrid拼接，存储该用户的购物车对应商品的详情

        //取出商品id集合转化为数组方便遍历
        $cartAttridArray = Redis::sMembers($cartGoods);

        //准备空数组和空总价接受遍历出来的数据
        $cartInfos = [];
        $total = 0;
        foreach ($cartAttridArray as $v) {
          $cartInfos[$v] = [
              'brand'    => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'brand'),
              'name'     => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'name'),
              'desc'     => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'desc'),
              'color'    => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'color'),
              'size'     => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'size'),
              'price'    => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'price'),
              'pic'      => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'pic'),
              'num'      => Redis::hGet($cartKey, $v),
              'money'    => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'price') * Redis::hGet($cartKey, $v),
              'attr_id'  => $v,
              'goods_id' => Goodsattr::find($v)->goods->id,
          ];

          $total += $cartInfos[$v]['money'];
        }

        // 友情链接
        $showLinks = new ShowLinksController;
        $linksArray = $showLinks->index();

        //引入站点信息
        $sate = IndexApi::getSate();

        return view('Home.goods-shopcart', ['cartInfos' => $cartInfos, 'total' => $total, 'linksArray' => $linksArray, 'sate' => $sate]);

    }

    /**
     * Show the form for creating a new resource.
     * 这个方法用来处理用户点击商品详情页面的加入购物车按钮/
     * $num商品数量
     * @return \Illuminate\Http\Response
     */
    public function addToCart(Request $request)
    {
        //获取详情页传递过来的商品属性id和数量number
        $attr_id = intval($request->attr_id);

        $num = intval($request->number);

        //获取用户的sessionid
        $session_id = session()->getId();

        //拼接好redis中哈希的key(存储用户购物车的核心数据:商品属性id和数量)
        $cartKey = 'user_cart_attrid_num_hash_'.$session_id;

        //拼接好redis中集合的键(存储用户购物车的所有商品属性id的集合，便于在购物车界面遍历数据)
        $cartGoods = 'user_cart_attrid_set_'.$session_id;

        //拼接好用户已经添加进购物车的商品属性的哈希的key(存储该用户购物车的单个商品各属性，存储在redis中减轻数据库压力)
        $cartGoodsInfoKey = 'user_cart_attrid_detail_hash_'.$session_id.'_'.$attr_id;

        //判断该商品属性id是否存在，防止用户而已篡改,还要判断所属商品是否已下架
        $idExists = Goodsattr::find($attr_id);
        $idStatus = $idExists->goods->status;
        if (!$idExists || $idStatus != 0) {
            return response()->json([
              'status' => 400,
              'msg' => '该商品不存在',
            ]);
        }

        $gid = Goodsattr::find($attr_id)->goods->id;
        //判断该属性id的库存是否足够，
        $reserve = Goodsattr::find($attr_id)->reserve;
        if ($reserve < $num) {
            return response()->json([
              'status' => 401,
              'msg' => '库存不足',
            ]);
        }


        //来到这里说明id和num都正常，再根据商品属性id查商品各属性(品牌|品名|描述|颜色|价格(如果是促销就用促销价)|)
        //模型关联用的多，储存起来减轻数据库的压力
        $attrs = Goodsattr::find($attr_id);
        $attrs_goodsinfo = $attrs->goods;


        //判断redis中是否之前已经有该商品
        if (Redis::hExists($cartKey, $attr_id)) {

            //判断该用户购物车的数量加上详情选购的数量不能大于库存
            $cartOriginalNum = Redis::hGet($cartKey, $attr_id);
            if ($cartOriginalNum + $num > $reserve) {
                return response()->json([
                    'status' => 500,
                    'msg' => '库存不足，请手下留情',
                ]);
            }

            //走到这里说明redis中已经有同类商品了，只需要把数量累加上去即可
            Redis::hIncrby($cartKey, $attr_id, $num);
            //把最新的库存响应给前台修改库存显示
            return response()->json([
              'status' => 201,
              'reserve' => 'OK',
            ]);
        } else {
            //走到这里说明redis中没有同类商品，把商品属性id和数量都追加进去

            Redis::hMset($cartKey, $attr_id, $num);

            //把商品的id追加入集合方便在购物车界面遍历
            Redis::sAdd($cartGoods, $attr_id);

            //获取商品的详细信息
            $brand = $attrs_goodsinfo->brands->brand_name;
            $name = $attrs_goodsinfo->goods_name;
            $desc = $attrs_goodsinfo->specs->goods_desc;
            $color = $attrs->color;
            $size = $attrs->size;
            $pic = $attrs_goodsinfo->goods_pic;

            //根据是否促销查对应的价格
            // dd($attrs_goodsinfo->promate);
            if ($attrs_goodsinfo->promate == 1) {
                //走到这里说明是促销品，再去促销表查价格
                $price = Goodsattr::find($attr_id)->goods->sales->promate_price;
            } else {
                $price = $attrs_goodsinfo->price;
            }

            //上面已经把购物车需要显示的信息都查到，再放入该用户对应的redis数据，以便快速展示在购物车页面
            Redis::hMset($cartGoodsInfoKey, 'brand', $brand, 'name', $name, 'desc', $desc, 'color', $color, 'size', $size, 'price', $price, 'pic', $pic);
            // var_dump(Redis::sMembers($cartGoods), Redis::hGetAll($cartKey), Redis::hGetAll($cartGoodsInfoKey));
            //把最新的库存响应给前台修改库存显示
            return response()->json([
              'status' => 202,
              'reserve' => 'OK',
            ]);
        }
    }

    /**
     * Store a newly created resource in storage.
     * 处理购物车界面对商品的加加按钮
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response 返回的是一个状态码，200代表成功，404代表加加失败
     */
    public function addNum(Request $request)
    {
        //先判断数据是否合法，购物车是否有该商品
        //.....
        $attr_id = intval($request->attr_id);
        $session_id = session()->getId();
        $cartGoods = 'user_cart_attrid_set_'.$session_id;//redis中储存的是用户的购物车所有商品属性id的集合
        $cartKey = 'user_cart_attrid_num_hash_'.$session_id;//redis中储存的是用户的商品属性id和对应的数量哈希
        $cartGoodsInfoKey = 'user_cart_attrid_detail_hash_';//redis中跟sessionid和attrid拼接，存储该用户的购物车对应商品的详情哈希

        //商品数量改变前，先判断仓库是否有货
        $reserve = Goodsattr::find($attr_id)->reserve;

        //判断购物车的商品数量不能大于库存量
        $num = Redis::hGet($cartKey, $attr_id);
        if ($reserve == $num) {
            return response()->json([
                'status' => 404,
                'msg' => '库存不足，还请手下留情',
            ]);
        }

        //走到这里把购物车的该商品数量加1
        $num = Redis::hIncrby($cartKey, $attr_id, 1);
        $price = Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$attr_id, 'price');
        $money = $num * $price;

        //计算好增加商品后的购物车数据
        $cartAttridArray = Redis::sMembers($cartGoods);
        $cartInfos = [];
        $total = 0;
        foreach ($cartAttridArray as $v) {
          $cartInfos[$v] = [
              'price' => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'price'),
              'num' => Redis::hGet($cartKey, $v),
              'money' => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'price') * Redis::hGet($cartKey, $v),
          ];

          $total += $cartInfos[$v]['money'];
        }

        //将数据响应给前台
        return response()->json([
            'status' => 200,
            'num' => $num,
            'money' => $money,
            'total' => $total,
        ]);

    }

    /**
     * Store a newly created resource in storage.
     * 处理购物车界面对商品的减减按钮
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response 返回的是一个状态码，200代表成功，404代表减减失败
     */
    public function cutNum(Request $request)
    {
        //先判断数据是否合法，购物车是否有该商品
        //.....
        $attr_id = intval($request->attr_id);
        $session_id = session()->getId();
        $cartGoods = 'user_cart_attrid_set_'.$session_id;//redis中储存的是用户的购物车所有商品属性id的集合
        $cartKey = 'user_cart_attrid_num_hash_'.$session_id;//redis中储存的是用户的商品属性id和对应的数量哈希
        $cartGoodsInfoKey = 'user_cart_attrid_detail_hash_';//redis中跟sessionid和attrid拼接，存储该用户的购物车对应商品的详情哈希

        //获取购物车该商品的原本数量
        $num = Redis::hGet($cartKey, $attr_id);

        //商品数量改变前，先判断当前的数量，不能小于1
        if ($num == 1) {
            return response()->json([
                'status' => '404',
                'msg' => '千山万水总是情，您买一件行不行~~~~(>_<)~~~~',
            ]);
        }

        $num = Redis::hIncrby($cartKey, $attr_id, -1);

        $price = Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$attr_id, 'price');
        $money = $num * $price;

        //计算好减少商品后的购物车数据响应给前台
        $cartAttridArray = Redis::sMembers($cartGoods);
        $cartInfos = [];
        $total = 0;
        foreach ($cartAttridArray as $v) {
          $cartInfos[$v] = [
              'price' => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'price'),
              'num' => Redis::hGet($cartKey, $v),
              'money' => Redis::hGet($cartGoodsInfoKey.$session_id.'_'.$v, 'price') * Redis::hGet($cartKey, $v),
          ];

          $total += $cartInfos[$v]['money'];
        }

        //将减完后的数据JSON格式传递到前台
        return response()->json([
            'status' => 200,
            'num' => $num,
            'money' => $money,
            'total' => $total,
        ]);

    }


    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     * 接收前台AJAX传递过来的id将对应的商品信息从购物车中删掉
     * @return \Illuminate\Http\Response 响应回去的是状态码，404表示失败, 200表示成功
     */
    public function destroy(Request $request)
    {
        $attr_id = $request->attr_id;
        //判断数据库+购物车是否有该商品
        // ........

        $session_id = session()->getId();
        $cartGoods = 'user_cart_attrid_set_'.$session_id;//redis中储存的是用户的购物车所有商品属性id的集合
        $cartKey = 'user_cart_attrid_num_hash_'.$session_id;//redis中储存的是用户的商品属性id和对应的数量哈希
        $cartGoodsInfoKey = 'user_cart_attrid_detail_hash_';//redis中跟sessionid和attrid拼接，存储该用户的购物车对应商品的详情哈希
        //将redis中用户对应的商品删掉
        $detail = Redis::del($cartGoodsInfoKey.$session_id.'_'.$attr_id);//删除商品的详细属性
        if ($detail != 1) {
            return response()->json([
                'status' => 404,
                'msg' => '删除失败，不要瞎搞',
            ]);
        }

        //删除购物车对应的属性id和数量
        $hash = Redis::hDel($cartKey, $attr_id);
        if ($hash != 1) {
            return response()->json([
                'status' => 404,
                'msg' => '删除失败，不要瞎搞',
            ]);
        }

        //删除集合中对应的属性id
        $set = Redis::sRem($cartGoods, $attr_id);
        if ($set != 1) {
            return response()->json([
                'status' => 404,
                'msg' => '删除失败，不要瞎搞',
            ]);
        }

        return response()->json([
            'status' => 200,
            'msg' => '删除成功',
        ]);

    }


    public function showCartNumber()
    {
        $homeCartNumber = new HomeCartNumber;
        $originalNum = $homeCartNumber::index();
        return $originalNum;
    }



}
